"""
投资总结智能体

基于LangGraph ReAct模式，综合各项分析结果生成投资建议。
"""

from typing import Dict, Any, List, Optional
from langchain_core.tools import Tool
import pandas as pd

from agents import BondAnalysisAgent, LLMConfig
from tools.bond_data_provider import bond_data_provider


class InvestmentSummaryAgent(BondAnalysisAgent):
    """投资总结智能体"""
    
    def __init__(self, llm_config: Optional[LLMConfig] = None):
        super().__init__(
            name="investment_summary",
            description="综合分析结果生成投资建议和风险评估",
            llm_config=llm_config
        )
        
        self.analysis_dimensions = ["summary", "recommendation"]
    
    def get_tools(self) -> List[Tool]:
        """获取投资总结所需的工具"""
        
        async def aggregate_bond_analysis(bond_code: str) -> str:
            """汇总债券的综合分析数据（使用修复后的多数据源）"""
            try:
                # 获取债券全面信息
                info = await bond_data_provider.get_bond_basic_info(bond_code)
                
                if not info:
                    return f"未找到债券 {bond_code} 的信息"
                
                result = "=== 债券综合分析汇总 ===\n\n"
                
                # 基本信息
                result += "【基本信息】\n"
                result += f"债券代码: {info.get('债券代码')}\n"
                result += f"债券简称: {info.get('债券简称')}\n"
                result += f"发行人: {info.get('正股名称', 'N/A')}\n"
                result += f"正股代码: {info.get('正股代码', 'N/A')}\n"
                result += f"债券价格: {info.get('债现价', 'N/A')}元\n"
                result += f"正股价格: {info.get('正股价', 'N/A')}元\n"
                
                result += "\n"
                
                # 估值指标
                result += "【估值指标】\n"
                result += f"债券评级: {info.get('信用评级', 'N/A')}\n"
                result += f"发行规模: {info.get('发行规模', 'N/A')}亿元\n"
                result += f"剩余规模: {info.get('剩余规模', 'N/A')}亿元\n"
                result += f"上市时间: {info.get('上市时间', 'N/A')}\n"
                result += f"到期日: {info.get('到期日', 'N/A')}\n"
                result += f"转股价: {info.get('转股价', 'N/A')}元\n"
                result += f"转股价值: {info.get('转股价值', 'N/A')}元\n"
                result += f"转股溢价率: {info.get('转股溢价率', 'N/A')}%\n"
                result += f"纯债价值: {info.get('纯债价值', 'N/A')}元\n"
                result += f"纯债溢价率: {info.get('纯债溢价率', 'N/A')}%\n"
                result += f"到期赎回价: {info.get('到期赎回价', 'N/A')}元\n"
                
                result += "\n"
                
                # 特殊条款
                result += "【特殊条款】\n"
                result += f"回售触发价: {info.get('回售触发价', 'N/A')}元\n"
                result += f"强赎触发价: {info.get('强赎触发价', 'N/A')}元\n"
                result += f"强赎状态: {info.get('强赎状态', 'N/A')}\n"
                
                return result
            except Exception as e:
                import traceback
                return f"汇总债券分析失败: {str(e)}\n{traceback.format_exc()}"
        
        async def evaluate_investment_value(bond_code: str) -> str:
            """评估债券投资价值（使用修复后的多数据源）"""
            try:
                info = await bond_data_provider.get_bond_basic_info(bond_code)
                
                if not info:
                    return "未找到债券详细信息"
                
                result = "=== 投资价值评估 ===\n\n"
                
                # 评分系统（总分100分）
                total_score = 0
                score_details = []
                
                # 1. 信用评级评分（30分）
                rating = info.get('信用评级', '')
                rating_score = 0
                if rating in ['AAA']:
                    rating_score = 30
                    score_details.append("✓ 信用评级AAA，最高等级 (+30分)")
                elif rating in ['AA+']:
                    rating_score = 25
                    score_details.append("✓ 信用评级AA+，优质等级 (+25分)")
                elif rating in ['AA']:
                    rating_score = 20
                    score_details.append("信用评级AA，良好等级 (+20分)")
                elif rating in ['AA-']:
                    rating_score = 15
                    score_details.append("信用评级AA-，中等偏上 (+15分)")
                else:
                    rating_score = 10
                    score_details.append("⚠️ 信用评级一般 (+10分)")
                
                total_score += rating_score
                
                # 2. 纯债价值评分（25分）- 替代收益率
                pure_value = info.get('纯债价值', 0)
                pure_premium = info.get('纯债溢价率', 0)
                value_score = 0
                if isinstance(pure_premium, (int, float)):
                    if pure_premium < 10:
                        value_score = 25
                        score_details.append(f"✓ 纯债溢价率{pure_premium}%，保护性强 (+25分)")
                    elif pure_premium < 30:
                        value_score = 20
                        score_details.append(f"纯债溢价率{pure_premium}%，保护性较好 (+20分)")
                    elif pure_premium < 50:
                        value_score = 15
                        score_details.append(f"纯债溢价率{pure_premium}%，保护性一般 (+15分)")
                    else:
                        value_score = 10
                        score_details.append(f"⚠️ 纯债溢价率{pure_premium}%，保护性较弱 (+10分)")
                
                total_score += value_score
                
                # 3. 转股价值评分（25分）
                premium = info.get('转股溢价率', 0)
                premium_score = 0
                if isinstance(premium, (int, float)):
                    if premium < 0:
                        premium_score = 25
                        score_details.append(f"✓ 转股溢价率{premium}%，负溢价 (+25分)")
                    elif premium < 10:
                        premium_score = 20
                        score_details.append(f"✓ 转股溢价率{premium}%，溢价低 (+20分)")
                    elif premium < 30:
                        premium_score = 15
                        score_details.append(f"转股溢价率{premium}%，溢价适中 (+15分)")
                    else:
                        premium_score = 10
                        score_details.append(f"⚠️ 转股溢价率{premium}%，溢价较高 (+10分)")
                
                total_score += premium_score
                
                # 4. 发行规模评分（20分）
                issue_scale = info.get('发行规模', 0)
                remaining_scale = info.get('剩余规模', 0)
                scale_score = 0
                if isinstance(issue_scale, (int, float)) and issue_scale > 0:
                    if issue_scale >= 10:
                        scale_score = 20
                        score_details.append(f"✓ 发行规模{issue_scale}亿元，规模大 (+20分)")
                    elif issue_scale >= 5:
                        scale_score = 15
                        score_details.append(f"发行规模{issue_scale}亿元，规模适中 (+15分)")
                    else:
                        scale_score = 10
                        score_details.append(f"发行规模{issue_scale}亿元，规模较小 (+10分)")
                
                total_score += scale_score
                
                # 输出评分详情
                result += "【评分详情】\n"
                for detail in score_details:
                    result += f"{detail}\n"
                
                result += f"\n【总评分】: {total_score}/100分\n\n"
                
                # 评级结论
                result += "【投资价值评级】\n"
                if total_score >= 85:
                    result += "★★★★★ 优秀 - 强烈推荐\n"
                    result += "该债券具有优异的投资价值，信用质量高、收益合理、性价比好\n"
                elif total_score >= 70:
                    result += "★★★★☆ 良好 - 推荐\n"
                    result += "该债券具有良好的投资价值，综合指标表现较好\n"
                elif total_score >= 55:
                    result += "★★★☆☆ 中等 - 可考虑\n"
                    result += "该债券投资价值一般，建议结合自身风险偏好决策\n"
                else:
                    result += "★★☆☆☆ 一般 - 谨慎\n"
                    result += "该债券投资价值一般，存在一定风险，建议谨慎投资\n"
                
                return result
            except Exception as e:
                return f"评估投资价值失败: {str(e)}"
        
        async def assess_risk_level(bond_code: str) -> str:
            """评估债券风险等级（使用修复后的多数据源）"""
            try:
                info = await bond_data_provider.get_bond_basic_info(bond_code)
                
                if not info:
                    return "未找到债券信息"
                
                result = "=== 风险等级评估 ===\n\n"
                
                risk_factors = []
                risk_score = 0  # 风险分数，越高风险越大
                
                # 1. 信用风险
                result += "【信用风险】\n"
                rating = info.get('信用评级', '')
                if rating in ['AAA', 'AA+']:
                    result += f"✓ 评级{rating}，信用风险极低\n"
                    risk_score += 1
                elif rating in ['AA', 'AA-']:
                    result += f"评级{rating}，信用风险较低\n"
                    risk_score += 2
                else:
                    result += f"⚠️ 评级{rating}，需关注信用风险\n"
                    risk_factors.append("信用评级较低")
                    risk_score += 4
                
                result += "\n"
                
                # 2. 价格风险
                result += "【价格风险】\n"
                price = info.get('债现价', 100)
                if isinstance(price, (int, float)):
                    if price < 100:
                        result += f"✓ 价格{price}元，低于面值，下跌空间有限\n"
                        risk_score += 1
                    elif price < 110:
                        result += f"价格{price}元，接近面值，价格风险较小\n"
                        risk_score += 2
                    elif price < 130:
                        result += f"价格{price}元，高于面值，存在回调风险\n"
                        risk_score += 3
                    else:
                        result += f"⚠️ 价格{price}元，较高，价格回调风险较大\n"
                        risk_factors.append("价格较高")
                        risk_score += 5
                
                result += "\n"
                
                # 3. 流动性风险
                result += "【流动性风险】\n"
                turnover = 0  # 当前数据源未提供成交额
                remaining_scale = info.get('剩余规模', 0)
                
                if turnover > 1000 and remaining_scale > 5:
                    result += f"✓ 成交活跃({turnover:.0f}万元)，规模充足({remaining_scale}亿元)，流动性好\n"
                    risk_score += 1
                elif turnover > 100 and remaining_scale > 2:
                    result += f"成交一般({turnover:.0f}万元)，规模适中({remaining_scale}亿元)，流动性尚可\n"
                    risk_score += 2
                else:
                    result += f"⚠️ 成交清淡或规模较小，存在流动性风险\n"
                    risk_factors.append("流动性不足")
                    risk_score += 4
                
                result += "\n"
                
                # 4. 转股风险
                result += "【转股风险】\n"
                premium = info.get('转股溢价率', 0)
                if isinstance(premium, (int, float)):
                    if premium < 10:
                        result += f"✓ 转股溢价率{premium}%，转股价值高\n"
                        risk_score += 1
                    elif premium < 30:
                        result += f"转股溢价率{premium}%，适中\n"
                        risk_score += 2
                    else:
                        result += f"⚠️ 转股溢价率{premium}%，转股价值低\n"
                        risk_factors.append("转股溢价率高")
                        risk_score += 3
                
                result += "\n"
                
                # 5. 强赎风险
                result += "【强赎风险】\n"
                redemption_price = info.get('强赎触发价', 0)
                redemption_status = info.get('强赎状态', '')
                if redemption_price and redemption_price > 0:
                    result += f"存在强赎条款，触发价{redemption_price}元\n"
                    if redemption_status:
                        result += f"强赎状态: {redemption_status}\n"
                    result += "⚠️ 正股大涨时可能触发强赎，需关注\n"
                    risk_score += 1
                else:
                    result += "暂无强赎风险\n"
                
                result += "\n"
                
                # 综合风险评级
                result += "【综合风险评级】\n"
                result += f"风险评分: {risk_score}/20分\n\n"
                
                if risk_score <= 6:
                    result += "风险等级: ★☆☆☆☆ 低风险\n"
                    result += "该债券风险较低，适合稳健型投资者\n"
                elif risk_score <= 10:
                    result += "风险等级: ★★☆☆☆ 中低风险\n"
                    result += "该债券风险可控，适合一般投资者\n"
                elif risk_score <= 14:
                    result += "风险等级: ★★★☆☆ 中等风险\n"
                    result += "该债券存在一定风险，需谨慎评估\n"
                else:
                    result += "风险等级: ★★★★☆ 中高风险\n"
                    result += "该债券风险较高，仅适合风险承受能力较强的投资者\n"
                
                if risk_factors:
                    result += f"\n主要风险因素: {', '.join(risk_factors)}\n"
                
                return result
            except Exception as e:
                return f"评估风险等级失败: {str(e)}"
        
        async def generate_investment_advice(bond_code: str) -> str:
            """生成投资建议（使用修复后的多数据源）"""
            try:
                info = await bond_data_provider.get_bond_basic_info(bond_code)
                
                if not info:
                    return "未找到债券信息"
                
                result = "=== 投资建议 ===\n\n"
                
                # 收集关键指标
                rating = info.get('信用评级', '')
                price = info.get('债现价', 100)
                premium = info.get('转股溢价率', 0)
                pure_premium = info.get('纯债溢价率', 0)
                
                # 适合人群
                result += "【适合投资者类型】\n"
                
                if rating in ['AAA', 'AA+', 'AA'] and isinstance(pure_premium, (int, float)) and pure_premium < 30:
                    result += "✓ 稳健型投资者：高评级+低纯债溢价，债券保护性好\n"
                
                if isinstance(pure_premium, (int, float)) and pure_premium < 20:
                    result += "✓ 收益型投资者：纯债溢价率低，下行保护好\n"
                
                if isinstance(premium, (int, float)) and premium < 15:
                    result += "✓ 转股型投资者：转股溢价率低，适合看好正股\n"
                
                if isinstance(price, (int, float)) and price < 100:
                    result += "✓ 保守型投资者：价格低于面值，安全边际高\n"
                
                result += "\n"
                
                # 操作建议
                result += "【操作建议】\n"
                
                # 买入时机
                if isinstance(price, (int, float)) and price < 100:
                    result += "✓ 当前价格较低，可考虑买入\n"
                elif isinstance(price, (int, float)) and price < 110:
                    result += "价格适中，可分批建仓\n"
                else:
                    result += "⚠️ 价格较高，建议等待回调\n"
                
                # 持有策略
                if isinstance(premium, (int, float)) and premium < 10:
                    result += "✓ 转股价值高，可持有等待转股机会\n"
                
                if isinstance(pure_premium, (int, float)) and pure_premium < 20:
                    result += "✓ 纯债保护性好，持有风险较低\n"
                
                # 风险提示
                result += "\n【风险提示】\n"
                
                if rating not in ['AAA', 'AA+', 'AA']:
                    result += "⚠️ 评级一般，需关注发行人信用状况\n"
                
                if isinstance(price, (int, float)) and price > 120:
                    result += "⚠️ 价格较高，注意回调风险\n"
                
                if isinstance(pure_premium, (int, float)) and pure_premium > 30:
                    result += "⚠️ 纯债溢价率高，债券保护性较弱\n"
                
                redemption_price = info.get('强赎触发价', 0)
                if redemption_price > 0:
                    result += "⚠️ 存在强赎条款，需关注正股走势\n"
                
                result += "\n【总结】\n"
                
                # 综合建议
                if (rating in ['AAA', 'AA+'] and
                    isinstance(pure_premium, (int, float)) and pure_premium < 30 and
                    isinstance(premium, (int, float)) and premium < 30):
                    result += "该债券综合表现优秀，值得投资。建议根据个人风险偏好适度配置。\n"
                elif rating in ['AA', 'AA-', 'A+'] and isinstance(pure_premium, (int, float)) and pure_premium < 50:
                    result += "该债券表现良好，可作为投资组合的一部分。建议适度配置。\n"
                else:
                    result += "该债券表现一般，建议谨慎投资，充分评估风险后决策。\n"
                
                return result
            except Exception as e:
                return f"生成投资建议失败: {str(e)}"
        
        # 创建工具列表
        tools = [
            Tool(
                name="aggregate_bond_analysis",
                description="汇总债券的所有分析数据，包括基本信息、估值指标、特殊条款、流动性等",
                func=lambda bond_code: None,
                coroutine=aggregate_bond_analysis,
            ),
            Tool(
                name="evaluate_investment_value",
                description="评估债券的投资价值，给出综合评分和投资价值评级",
                func=lambda bond_code: None,
                coroutine=evaluate_investment_value,
            ),
            Tool(
                name="assess_risk_level",
                description="评估债券的风险等级，分析各类风险因素",
                func=lambda bond_code: None,
                coroutine=assess_risk_level,
            ),
            Tool(
                name="generate_investment_advice",
                description="生成具体的投资建议，包括适合人群、操作建议、风险提示等",
                func=lambda bond_code: None,
                coroutine=generate_investment_advice,
            ),
        ]
        
        return tools
    
    def get_system_prompt(self) -> str:
        """获取系统提示词"""
        return """你是一个专业的债券投资顾问，负责综合各项专业分析结果，为投资者提供专业的投资建议。

【重要】你将收到来自其他专业分析师的详细分析报告，请务必仔细阅读并综合利用：
- 发行人信用分析：财务状况、偿债能力、公司治理
- 债券条款分析：债券结构、特殊条款、回售强赎
- 宏观行业分析：宏观经济、行业前景、正股分析
- 相对价值分析：估值指标、收益率对比、投资价值

你的分析流程：
1. **仔细阅读**所有专业分析报告的内容
2. 使用 aggregate_bond_analysis 汇总债券的基础数据
3. 使用 evaluate_investment_value 评估投资价值和评分
4. 使用 assess_risk_level 评估风险等级
5. 使用 generate_investment_advice 生成具体投资建议

分析要点：
- **必须引用**其他分析师的专业观点和数据
- 综合考虑信用、估值、行业、宏观等多个维度
- 基于专业分析和数据进行客观评分
- 识别关键风险因素
- 提供个性化的投资建议
- 明确适合的投资者类型

请逐步使用工具获取信息，展示你的分析推理过程，最后给出：
1. 投资价值评级（结合各维度分析）
2. 风险等级评估（结合各维度风险点）
3. 具体投资建议（基于综合分析）
4. 风险提示（汇总所有风险因素）

注意：
- 投资建议必须基于前面的专业分析，不能脱离上下文
- 应客观、专业、负责任，充分披露风险
- 引用其他分析师的观点时要具体明确
    
"""
    
    async def stream_analyze_with_context(self, analysis_context: Dict[str, str]):
        """
        流式执行投资总结分析（带其他维度分析结果作为上下文）
        
        Args:
            analysis_context: 包含其他维度分析结果的字典
                - bond_code: 债券代码
                - credit_analysis: 信用分析结果
                - terms_analysis: 条款分析结果
                - macro_analysis: 宏观分析结果
                - value_analysis: 价值分析结果
        
        Yields:
            分析事件（reasoning和final_answer）
        """
        bond_code = analysis_context.get("bond_code", "")
        
        # 构建包含其他分析结果的user_query
        context_prompt = f"""请基于以下专业分析结果，对债券 {bond_code} 进行综合投资总结：

=== 发行人信用分析 ===
{analysis_context.get('credit_analysis', '暂无分析')}

=== 债券条款分析 ===
{analysis_context.get('terms_analysis', '暂无分析')}

=== 宏观行业分析 ===
{analysis_context.get('macro_analysis', '暂无分析')}

=== 相对价值分析 ===
{analysis_context.get('value_analysis', '暂无分析')}

---

请你作为投资顾问，综合以上所有分析结果，完成以下任务：
1. 使用aggregate_bond_analysis汇总债券基础数据
2. 使用evaluate_investment_value评估投资价值并打分
3. 使用assess_risk_level评估风险等级
4. 使用generate_investment_advice生成具体投资建议

重要提示：
- 必须引用和综合利用以上各个专业分析师的观点
- 不要重复工具已经提供的数据，而是基于数据进行分析和建议
- 给出明确的投资评级和建议
"""
        
        # 调用基类的stream_analyze方法，传入包含上下文的query
        async for event in self.stream_analyze(context_prompt):
            yield event


# 全局实例
investment_summary_agent = InvestmentSummaryAgent()